﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Management;
using System.Security.Cryptography;
using System.Collections;
using System.Text.RegularExpressions;

namespace CDKey
{
    public class Register
    {
        private string CDKey;
        private string RegCode;

        public Register()
        {
            RegCode = GenerateRegCode();
        }
        public Register(string regcode)
        {
            RegCode = regcode;
        }

        public bool CheckCdKey(string CDKey)
        {
            this.CDKey = GenerateCDKey(RegCode);
            return this.CDKey == CDKey;
        }

        public string GetRegCode()
        {
            return RegCode;
        }

        private string GenerateRegCode()
        {
            string strSerial = GenerateSerial();
            string strRegCode = "";
            for (int i = 0; i < strSerial.Length; i++)
            {
                if (i % 2 == 0)
                {
                    strRegCode += strSerial[i];
                }
            }
            strRegCode = strRegCode + "MSJD2YQPLZYXUD8294620USLQ";
            string strRet = "";
            for (var i = 0; i < 16; i++)
            {
                strRet += strRegCode[i];
                if (((i + 1) % 4 == 0)&&(i<15))
                    strRet += "-";
            }
            return strRet;

        }

        public string GenerateCDKey(string Source)
        {
            Regex rgx = new Regex("[^A-Z0-9]");
            Source = rgx.Replace(Source, "");

            string Result = "";
            string[] A1 = { "Z", "1", "E", "7", "T", "Y", "9", "I", "6", "P", "L", "K", "J", "H", "G", "3", "D", "S", "A", "Z", "X", "Q", "V", "B", "N", "M" };
            string[] A2 = { "2", "T", "5", "8", "W", "0", "I", "Z", "G", "P", "O", "H", "L", "K", "3", "7", "S", "D", "F", "C", "V", "Z", "P", "M", "J", "B" };
            if (Source != "")
            {
                Result = this.CryptographyMD5(Source);
                char[] A = Result.ToCharArray(0, Result.Trim().Length);
                for (int i = 0; i < A.Length; i++)
                {
                    if (i % 3 == 1)
                    {
                        Result += A[i];
                    }
                }
                char[] B = Result.Trim().ToCharArray(0, Result.Trim().Length);
                Result = "";
                for (int j = 0; j < 20; j++)
                {
                    if (j % 3 == 1)
                    {
                        Result += A1[int.Parse(A[j].ToString())];
                    }
                    else
                    {
                        Result += A2[int.Parse(A[j].ToString())];
                    }
                }
            }
            Result = Result + "MSJHDUA872HS0928KSHNALQTWYX415278";
            string strRet = "";
            for (var i = 0; i < 16; i++)
            {
                strRet += Result[i];
                if (((i + 1) % 4 == 0) && (i < 15))
                    strRet += "-";
            }
            return strRet;            
        }

        private string GenerateSerial()
        {
            try
            {
                string HddSerial = GetHddSerial();
                string MD5Hashed = CreateMD5Hash(HddSerial);
                return MD5Hashed.ToUpper();
            }
            catch
            {
                return CreateMD5Hash("SU2DHE8346LKS34ID5HS2M4").ToUpper();
            }
        }

        private string GetHddSerial()
        {
            string serial = "";            
            try
            {
                ManagementObjectSearcher searcher = new
                    ManagementObjectSearcher("select * FROM  Win32_LogicalDiskToPartition");
                string Antecedent = "";
                foreach (ManagementObject wmi_HD in searcher.Get())
                {
                    if (wmi_HD["Dependent"].ToString().Contains("Win32_LogicalDisk.DeviceID=\"C:\""))
                        Antecedent = wmi_HD["Antecedent"].ToString();
                }
                string DeviceID = Antecedent.Split('=')[1].Trim();

                string DiskIndex = "";
                searcher = new
                    ManagementObjectSearcher("select * FROM  Win32_DiskPartition WHERE DeviceID=" + DeviceID);
                foreach (ManagementObject wmi_HD in searcher.Get())
                {
                    DiskIndex = wmi_HD["DiskIndex"].ToString();
                }


                searcher = new
                    ManagementObjectSearcher("SELECT * FROM Win32_DiskDrive WHERE Index=" + DiskIndex);
                string Name = "";
                foreach (ManagementObject wmi_HD in searcher.Get())
                {
                    Name = wmi_HD["Name"].ToString();
                    DeviceID = wmi_HD["DeviceID"].ToString();                    
                }

                searcher = new
                    ManagementObjectSearcher("SELECT * FROM Win32_PhysicalMedia");
                foreach (ManagementObject wmi_HD in searcher.Get())
                {
                    if ((wmi_HD["Tag"].ToString() == Name) || (wmi_HD["Tag"].ToString() == DeviceID))
                        serial = wmi_HD["SerialNumber"].ToString().Trim();
                }

            }
            catch
            {
                serial = "";
                ManagementObjectSearcher searcher = new
                   ManagementObjectSearcher("SELECT * FROM Win32_PhysicalMedia");
                foreach (ManagementObject wmi_HD in searcher.Get())
                {
                    serial += wmi_HD["SerialNumber"].ToString().Trim();
                }
            }
            return serial;
        }

        private string CreateMD5Hash(string input)
        {
            // Use input string to calculate MD5 hash
            MD5 md5 = System.Security.Cryptography.MD5.Create();
            byte[] inputBytes = System.Text.Encoding.ASCII.GetBytes(input);
            byte[] hashBytes = md5.ComputeHash(inputBytes);

            // Convert the byte array to hexadecimal string
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < hashBytes.Length; i++)
            {
                sb.Append(hashBytes[i].ToString("X2"));
                // To force the hex string to lower-case letters instead of
                // upper-case, use he following line instead:
                // sb.Append(hashBytes[i].ToString("x2")); 
            }
            return sb.ToString();
        }

        public string CryptographyMD5(string source)
        {
            string result = "";
            try
            {
                System.Security.Cryptography.MD5CryptoServiceProvider objMD5 = new System.Security.Cryptography.MD5CryptoServiceProvider();
                byte[] buffer = System.Text.Encoding.UTF8.GetBytes(source);
                byte[] bytHash = objMD5.ComputeHash(buffer);
                foreach (byte a in bytHash)
                {
                    result += int.Parse(a.ToString(), System.Globalization.NumberStyles.HexNumber).ToString();
                }
            }
            catch
            {
            }
            return result;
        }       
    }
}
